// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.repo

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import androidx.core.content.edit
import androidx.core.database.sqlite.transaction
import androidx.preference.PreferenceManager

class OfflineRepository(val context: Context) : Repository {
	private val db =
		SQLiteDatabase.openOrCreateDatabase(context.getDatabasePath("favourites").path, null)

	override suspend fun getFavourite(stopCode: String): Favourite? {
		val cursor =
			db.rawQuery(
				"select sequence, stop_name, feed_id, feed_name, lines from favourites where stop_code = ?",
				listOf(stopCode).toTypedArray()
			)
		if (cursor.count == 0) {
			return null
		}
		cursor.moveToNext()
		val f = Favourite(
			cursor.getInt(0),
			cursor.getString(2),
			cursor.getString(3),
			stopCode,
			cursor.getString(1),
			cursor.getString(4).split("||").filter { it != "" },
			false  // TODO get exact from database
		)
		cursor.close()
		return f
	}

	override suspend fun getFavourites(feedIDs: Set<String>): List<Favourite> {
		val whereClause = if (feedIDs.isNotEmpty()) {
			feedIDs.indices.joinToString(prefix = "where feed_id in (", postfix = ")") { "?" }
		} else {
			""
		}
		val cursor =
			db.rawQuery(
				"select sequence, stop_name, feed_id, feed_name, stop_code, lines from favourites $whereClause order by sequence",
				feedIDs.toTypedArray()
			)
		val l = mutableListOf<Favourite>()
		while (cursor.moveToNext()) {
			l.add(
				Favourite(
					cursor.getInt(0),
					cursor.getString(2),
					cursor.getString(3),
					cursor.getString(4),
					cursor.getString(1),
					cursor.getString(5).split("||").filter { it != "" },
					false // TODO get exact from database
				)
			)
		}
		cursor.close()
		return l
	}

	override suspend fun saveFavourite(favourite: Favourite) {
		val sequence = favourite.sequence ?: run {
			val cursor =
				db.rawQuery("select max(ROWID) from favourites", emptyArray<String?>())
			val s = if (cursor.count == 0) {
				0
			} else {
				cursor.moveToNext()
				cursor.getInt(0)
			}
			cursor.close()
			s
		}

		// XXX `on conflict` is not supported on older versions of Android
		val cursor = db.rawQuery(
			"select * from favourites where feed_id = ? and stop_code = ?",
			arrayOf(favourite.feedID, favourite.stopCode)
		)
		if (cursor.count > 0) {
			db.execSQL(
				"update favourites set stop_name = ?, lines = ?, sequence = ? where feed_id = ? and stop_code = ?",
				arrayOf<Any?>(
					favourite.stopName,
					favourite.lines.joinToString(separator = "||"),
					favourite.sequence,
					favourite.feedID,
					favourite.stopCode
				)
			)
		} else {
			db.execSQL(
				"insert into favourites(sequence, feed_id, feed_name, stop_code, stop_name, lines) values (?, ?,?,?,?,?)",
				arrayOf<Any?>(
					sequence,
					favourite.feedID,
					favourite.feedName,
					favourite.stopCode,
					favourite.stopName,
					favourite.lines.joinToString(separator = "||"),
				)
			)
		}
		cursor.close()
	}

	override suspend fun saveFavourites(favourites: Set<Favourite>) {
		db.execSQL("delete from favourites")
		db.transaction {
			favourites.forEach {
				saveFavourite(it)
			}
		}
	}

	fun close() {
		db.close()
	}

	fun saveSuperUser(value: Boolean) {
		PreferenceManager.getDefaultSharedPreferences(context).edit {
			putBoolean("superuser", value)
		}
	}


	fun getSuperUser(): Boolean {
		return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("superuser", false)
	}
}


fun migrateDB(context: Context) {
	val db = SQLiteDatabase.openOrCreateDatabase(context.getDatabasePath("favourites").path, null)
	db.execSQL("create table if not exists favourites(sequence integer, feed_id text, feed_name text, stop_code text, stop_name text, lines text, primary key(feed_id, stop_code))")
}
